package com.docmgmt.mvp.controller;

import com.docmgmt.mvp.dto.*;
import com.docmgmt.mvp.exception.ForbiddenException;
import com.docmgmt.mvp.exception.UnauthorizedException;
import com.docmgmt.mvp.service.PermissionService;
import com.docmgmt.mvp.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户管理控制器（v3.0 完整 CRUD + RBAC 权限）
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;
    private final PermissionService permissionService;

    /**
     * 创建用户
     *
     * POST /api/v1/users
     *
     * @param request 创建请求
     * @return 用户VO
     */
    @PostMapping
    public Result<UserVO> createUser(@Valid @RequestBody CreateUserRequest request) {
        Long currentUserId = getCurrentUserId();

        // 权限检查：user:create（需要管理员权限）
        if (!permissionService.checkPermission(currentUserId, "user", "create")) {
            throw new ForbiddenException("无权限创建用户");
        }

        log.info("POST /api/v1/users - currentUser={}, newUsername={}", currentUserId, request.getUsername());

        UserVO user = userService.createUser(request);
        return Result.success("用户创建成功", user);
    }

    /**
     * 获取用户列表
     *
     * GET /api/v1/users?page=1&page_size=20&keyword=zhang&status=active&department_id=1
     *
     * @param page          页码
     * @param pageSize      每页大小
     * @param keyword       搜索关键词
     * @param status        状态过滤
     * @param departmentId  部门过滤
     * @return 分页用户列表
     */
    @GetMapping
    public Result<PagedResult<UserVO>> listUsers(
            @RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "page_size", required = false) Integer pageSize,
            @RequestParam(value = "keyword", required = false) String keyword,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "department_id", required = false) Long departmentId) {

        Long currentUserId = getCurrentUserId();

        // 权限检查：user:read（普通用户可以查看用户列表）
        if (!permissionService.checkPermission(currentUserId, "user", "read")) {
            throw new ForbiddenException("无权限查看用户列表");
        }

        log.info("GET /api/v1/users - currentUser={}, page={}, keyword={}", currentUserId, page, keyword);

        PagedResult<UserVO> result = userService.listUsers(page, pageSize, keyword, status, departmentId);
        return Result.success(result);
    }

    /**
     * 获取用户详情
     *
     * GET /api/v1/users/{id}
     *
     * @param id 用户ID
     * @return 用户VO
     */
    @GetMapping("/{id}")
    public Result<UserVO> getUserDetail(@PathVariable Long id) {
        Long currentUserId = getCurrentUserId();

        // 权限检查：user:read
        if (!permissionService.checkPermission(currentUserId, "user:"+id, "read")) {
            throw new ForbiddenException("无权限查看该用户");
        }

        log.info("GET /api/v1/users/{} - currentUser={}", id, currentUserId);

        UserVO user = userService.getUserDetail(id);
        return Result.success(user);
    }

    /**
     * 更新用户
     *
     * PUT /api/v1/users/{id}
     *
     * @param id      用户ID
     * @param request 更新请求
     * @return 更新后的用户VO
     */
    @PutMapping("/{id}")
    public Result<UserVO> updateUser(
            @PathVariable Long id,
            @Valid @RequestBody UpdateUserRequest request) {

        Long currentUserId = getCurrentUserId();

        // 权限检查：user:update（需要管理员权限或本人）
        if (!permissionService.checkPermission(currentUserId, "user:"+id, "update")) {
            throw new ForbiddenException("无权限修改该用户");
        }

        log.info("PUT /api/v1/users/{} - currentUser={}", id, currentUserId);

        UserVO user = userService.updateUser(id, request);
        return Result.success("用户更新成功", user);
    }

    /**
     * 删除用户
     *
     * DELETE /api/v1/users/{id}
     *
     * @param id 用户ID
     * @return 成功响应
     */
    @DeleteMapping("/{id}")
    public Result<Void> deleteUser(@PathVariable Long id) {
        Long currentUserId = getCurrentUserId();

        // 权限检查：user:delete（需要管理员权限）
        if (!permissionService.checkPermission(currentUserId, "user", "delete")) {
            throw new ForbiddenException("无权限删除用户");
        }

        // 不允许删除自己
        if (id.equals(currentUserId)) {
            throw new ForbiddenException("不能删除自己的账号");
        }

        log.info("DELETE /api/v1/users/{} - currentUser={}", id, currentUserId);

        userService.deleteUser(id);
        return Result.success("用户删除成功");
    }

    /**
     * 修改密码
     *
     * PUT /api/v1/users/{id}/password
     *
     * @param id      用户ID
     * @param request 修改密码请求
     * @return 成功响应
     */
    @PutMapping("/{id}/password")
    public Result<Void> changePassword(
            @PathVariable Long id,
            @Valid @RequestBody ChangePasswordRequest request) {

        Long currentUserId = getCurrentUserId();

        // 只能修改自己的密码
        if (!id.equals(currentUserId)) {
            throw new ForbiddenException("只能修改自己的密码");
        }

        log.info("PUT /api/v1/users/{}/password - currentUser={}", id, currentUserId);

        userService.changePassword(id, request);
        return Result.success("密码修改成功");
    }

    /**
     * 重置密码（管理员操作）
     *
     * POST /api/v1/users/{id}/reset-password
     *
     * @param id          用户ID
     * @param newPassword 新密码
     * @return 成功响应
     */
    @PostMapping("/{id}/reset-password")
    public Result<Void> resetPassword(
            @PathVariable Long id,
            @RequestParam("new_password") String newPassword) {

        Long currentUserId = getCurrentUserId();

        // 权限检查：user:reset_password（需要管理员权限）
        if (!permissionService.checkPermission(currentUserId, "user", "reset_password")) {
            throw new ForbiddenException("无权限重置密码");
        }

        log.info("POST /api/v1/users/{}/reset-password - admin={}", id, currentUserId);

        userService.resetPassword(id, newPassword);
        return Result.success("密码重置成功");
    }

    /**
     * 分配角色
     *
     * PUT /api/v1/users/{id}/roles
     *
     * @param id    用户ID
     * @param roles 角色代码列表
     * @return 成功响应
     */
    @PutMapping("/{id}/roles")
    public Result<Void> assignRoles(
            @PathVariable Long id,
            @RequestBody List<String> roles) {

        Long currentUserId = getCurrentUserId();

        // 权限检查：user:assign_role（需要管理员权限）
        if (!permissionService.checkPermission(currentUserId, "user", "assign_role")) {
            throw new ForbiddenException("无权限分配角色");
        }

        log.info("PUT /api/v1/users/{}/roles - admin={}, roles={}", id, currentUserId, roles);

        userService.assignRolesToUser(id, roles);
        return Result.success("角色分配成功");
    }

    /**
     * 获取用户角色列表
     *
     * GET /api/v1/users/{id}/roles
     *
     * @param id 用户ID
     * @return 角色代码列表
     */
    @GetMapping("/{id}/roles")
    public Result<List<String>> getUserRoles(@PathVariable Long id) {
        Long currentUserId = getCurrentUserId();

        // 权限检查：user:read
        if (!permissionService.checkPermission(currentUserId, "user:"+id, "read")) {
            throw new ForbiddenException("无权限查看该用户");
        }

        log.info("GET /api/v1/users/{}/roles - currentUser={}", id, currentUserId);

        List<String> roles = userService.getUserRoles(id);
        return Result.success(roles);
    }

    /**
     * 更新存储配额
     *
     * PUT /api/v1/users/{id}/quota
     *
     * @param id    用户ID
     * @param quota 新配额（字节）
     * @return 成功响应
     */
    @PutMapping("/{id}/quota")
    public Result<Void> updateStorageQuota(
            @PathVariable Long id,
            @RequestParam("quota") Long quota) {

        Long currentUserId = getCurrentUserId();

        // 权限检查：user:update_quota（需要管理员权限）
        if (!permissionService.checkPermission(currentUserId, "user", "update_quota")) {
            throw new ForbiddenException("无权限修改存储配额");
        }

        log.info("PUT /api/v1/users/{}/quota - admin={}, quota={}", id, currentUserId, quota);

        userService.updateStorageQuota(id, quota);
        return Result.success("存储配额更新成功");
    }

    /**
     * 获取当前登录用户信息
     *
     * GET /api/v1/users/me
     *
     * @return 当前用户VO
     */
    @GetMapping("/me")
    public Result<UserVO> getCurrentUser() {
        Long currentUserId = getCurrentUserId();

        log.info("GET /api/v1/users/me - currentUser={}", currentUserId);

        UserVO user = userService.getUserDetail(currentUserId);
        return Result.success(user);
    }

    /**
     * 从Spring Security上下文获取当前用户ID
     */
    private Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new UnauthorizedException("未登录或认证已过期");
        }

        Object principal = authentication.getPrincipal();
        if (principal instanceof Long) {
            return (Long) principal;
        }

        throw new UnauthorizedException("无效的认证信息");
    }
}
